/**
 * Luat 系统错误日志管理服务器
 *  用于搜集 Luat 的错误上报
 * 
 *   gcc errDumpUdpServer.c -o errDumpUdpServer
*/

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <sys/socket.h>
#include <sys/types.h>

#include <netinet/in.h>
#include <arpa/inet.h>

#include <pthread.h>

int udpServerHander = 0;

#define UDP_SERVER_HOST "0.0.0.0"
#define UDP_SERVER_PORT 9595

static int udp_serverCreate(const char *host, const short port)
{
    assert(host != NULL);
    assert(port > 0);

    int ret = 0;

    if ((udpServerHander = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        return -1;
    }

    struct sockaddr_in serverAddr;
    memset(&serverAddr, 0, sizeof(struct sockaddr_in));
    struct hostent *hostname = NULL;

    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(port);

    if ((hostname = gethostbyname(host)) == NULL)
    {
        serverAddr.sin_addr.s_addr = inet_addr(host);
    }
    else
    {
        memcpy(&serverAddr.sin_addr, hostname->h_addr, hostname->h_length);
    }

    if ((ret = bind(udpServerHander, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr))) < 0)
    {
        close(udpServerHander);
        return -1;
    }

    return 0;
}

#define RECV_BUFF_MAX_LEN 2048
int main()
{
    udp_serverCreate(UDP_SERVER_HOST, UDP_SERVER_PORT);
    char buff[RECV_BUFF_MAX_LEN];

    struct sockaddr from;
    int fromAddrLen = sizeof(struct sockaddr);
    while (1)
    {
        memset(buff, 0, RECV_BUFF_MAX_LEN);
        memset(&from, 0, fromAddrLen);
        int ret = recvfrom(udpServerHander, buff, RECV_BUFF_MAX_LEN, 0, &from, &fromAddrLen);

        if ((ret == -1 && errno == EINTR) || ret == 0)
        {
            continue;
        }

        printf("%s\n", buff);

        sendto(udpServerHander, "OK", 2, 0, &from, fromAddrLen);
    }
}